package com.chengcang.admin.modules.busi.service.impl;

import cn.hutool.core.util.NumberUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.chengcang.admin.common.utils.UserUtils;
import com.chengcang.admin.modules.busi.dao.BusiAddressDao;
import com.chengcang.admin.modules.busi.dao.BusiDemandDao;
import com.chengcang.admin.modules.busi.dao.BusiDemandTenantDao;
import com.chengcang.admin.modules.busi.dao.BusiInvoiceHeadDao;
import com.chengcang.admin.modules.busi.dto.*;
import com.chengcang.admin.modules.busi.entity.*;
import com.chengcang.admin.modules.busi.service.*;
import com.chengcang.admin.modules.security.user.SecurityUser;
import com.chengcang.admin.modules.sys.dao.SysTenantBindingsDao;
import com.chengcang.admin.modules.sys.dao.SysTenantDao;
import com.chengcang.admin.modules.sys.dto.SysTenantDTO;
import com.chengcang.admin.modules.sys.entity.SysTenantBindingsEntity;
import com.chengcang.admin.modules.sys.entity.SysTenantEntity;
import com.chengcang.admin.modules.sys.service.SysDictDataService;
import com.chengcang.admin.modules.sys.service.SysProductService;
import com.chengcang.common.constant.Constant;
import com.chengcang.common.enums.DataTypeEnum;
import com.chengcang.common.exception.CustomException;
import com.chengcang.common.page.PageData;
import com.chengcang.common.service.impl.CrudServiceImpl;
import com.chengcang.common.utils.ConvertUtils;
import com.chengcang.common.utils.Result;
import com.chengcang.common.utils.SnowFlakeUtils;
import com.google.common.collect.Lists;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

import static java.util.stream.Collectors.toList;

/**
 * 需求实现
 *
 * @author bibajin
 * @since 1.0.0 2023-01-10
 */
@Service
public class BusiDemandServiceImpl extends CrudServiceImpl<BusiDemandDao, BusiDemandEntity, BusiDemandDTO> implements BusiDemandService {

    @Autowired
    private SysProductService sysProductService;

    @Autowired
    private BusiAddressDao busiAddressDao;

    @Autowired
    private BusiDemandDao busiDemandDao;

    @Autowired
    private BusiInvoiceHeadDao busiInvoiceHeadDao;

    @Autowired
    private BusiDemandTenantService busiDemandTenantService;

    @Autowired
    private SysTenantDao sysTenantDao;

    @Autowired
    private SysDictDataService sysDictDataService;

    @Autowired
    private BusiDemandTenantDao busiDemandTenantDao;

    @Autowired
    private SysTenantBindingsDao sysTenantBindingsDao;

    @Autowired
    private BusiFinanceService busiFinanceService;

    @Autowired
    private BusiDemandTenantSnapshotService busiDemandTenantSnapshotService;
    @Autowired
    private BusiDemandProductSnapshotService busiDemandProductSnapshotService;
    @Autowired
    private BusiDemandAddressSnapshotService busiDemandAddressSnapshotService;
    @Autowired
    private BusiDemandPerformanceSnapshotService busiDemandPerformanceSnapshotService;
    @Autowired
    private BusiDemandDemandSnapshotService busiDemandDemandSnapshotService;
    @Autowired
    private BusiDemandInvoiceHeadSnapshotService busiDemandInvoiceHeadSnapshotService;


    @Override
    public QueryWrapper<BusiDemandEntity> getWrapper(Map<String, Object> params) {
        String id = (String) params.get("id");

        QueryWrapper<BusiDemandEntity> wrapper = new QueryWrapper<>();
        wrapper.eq(StringUtils.isNotBlank(id), "id", id);

        return wrapper;
    }

    @Override
    public PageData<BusiDemandDTO> appoint(Map<String, Object> params) {
        // 设置自身客户类型，工厂不能看到公共池中的数据
        Long tenantId = SecurityUser.getTenantId();
        Optional.ofNullable(tenantId).ifPresent(o -> params.put("tenantId", tenantId));
        if (tenantId != null) {
            SysTenantEntity sysTenantEntity = sysTenantDao.selectById(tenantId);
            params.put("tenantSelfType", sysTenantEntity.getTenantType());
        }

        IPage<BusiDemandEntity> page = getPage(params, Constant.CREATE_DATE, false);
        List<BusiDemandDTO> list = baseDao.getAppointList(page, params);

        PageData<BusiDemandDTO> pageData = getPageData(list, page.getTotal(), BusiDemandDTO.class);

        complement(pageData);

        return pageData;
    }

    @Override
    public BusiDemandDTO getByDemandNo(String demandNo) {
        BusiDemandEntity entity = busiDemandDao.selectOne(Wrappers.<BusiDemandEntity>lambdaQuery().eq(BusiDemandEntity::getDemandNo, demandNo));
        BusiDemandDTO dto = new BusiDemandDTO();
        BeanUtils.copyProperties(entity, dto);
        return dto;
    }

    private void complement(PageData<BusiDemandDTO> pageData) {

        List<Long> tenantIdList = pageData.getList().stream().filter(o -> StringUtils.isNotBlank(o.getPerformanceId()))
                .flatMap(o -> Arrays.stream(o.getPerformanceId().split(",")))
                .map(Long::parseLong).distinct().collect(toList());
        Map<Long, Integer> tenantTypeMap = new HashMap<>();

        if (CollectionUtils.isNotEmpty(tenantIdList)) {
            tenantTypeMap = sysTenantDao.selectBatchIds(tenantIdList).stream().collect(Collectors.toMap(SysTenantEntity::getId, SysTenantEntity::getTenantType));
        }

        for (BusiDemandDTO busiDemandDTO : pageData.getList()) {
            //客户类型(履约客户)
            Map<Long, Integer> finalTenantTypeMap = tenantTypeMap;
            Optional.ofNullable(busiDemandDTO.getPerformanceId()).ifPresent(o -> {
                List<Long> performanceIds = Arrays.stream(busiDemandDTO.getPerformanceId().split(",")).map(Long::parseLong).collect(toList());
                Set<String> performanceNameSet = new HashSet<>();
                for (Long performanceId : performanceIds) {
                    performanceNameSet.add(sysDictDataService.getValue(DataTypeEnum.TENANT_TYPE, String.valueOf(finalTenantTypeMap.get(performanceId))));
                }
                busiDemandDTO.setPerformanceName(String.join(",", performanceNameSet));
            });
            //需求状态
            if (busiDemandDTO.getDemandStatus() != null) {
                busiDemandDTO.setDemandStatusName(sysDictDataService.getValue(DataTypeEnum.DEMAND_STATUS, String.valueOf(busiDemandDTO.getDemandStatus())));
            }
            //支付状态
            if (busiDemandDTO.getPayStatus() != null) {
                busiDemandDTO.setPayStatusName(sysDictDataService.getValue(DataTypeEnum.PAY_STATUS, String.valueOf(busiDemandDTO.getPayStatus())));
            }
            //需求货品 快照获取  TODO for 循环中查询数据
            //SysProductDTO detail = sysProductService.getDetail(busiDemandDTO.getProductId());
            BusiDemandProductSnapshotDTO productSnapshotDTO = busiDemandProductSnapshotService.get(busiDemandDTO.getProductId());
            if (productSnapshotDTO != null) {
                busiDemandDTO.setProductName(productSnapshotDTO.getName());
            }
            //需求来源
            if (busiDemandDTO.getDataSource() != null) {
                busiDemandDTO.setDataSourceName(sysDictDataService.getValue(DataTypeEnum.DATA_SOURCE, String.valueOf(busiDemandDTO.getDataSource())));
            }
            //需求来源类型
            if (busiDemandDTO.getDemandSourceType() != null) {
                busiDemandDTO.setDemandSourceTypeName(sysDictDataService.getValue(DataTypeEnum.DEMAND_SOURCE_TYPE, String.valueOf(busiDemandDTO.getDemandSourceType())));
            }
            //需求去向类型
            if (busiDemandDTO.getAssignType() != null) {
                busiDemandDTO.setAssignTypeName(sysDictDataService.getValue(DataTypeEnum.DEMAND_DIRECTION_TYPE, String.valueOf(busiDemandDTO.getAssignType())));
            }
        }
    }

    /**
     * 分页查询
     *
     * @param params
     * @return
     */
    @Override
    public PageData<BusiDemandDTO> page(Map<String, Object> params) {
        // 设置自身客户类型，工厂不能看到公共池中的数据
        Long tenantId = SecurityUser.getTenantId();
        if (!Objects.equals(tenantId, 1L)) {
            params.put("tenantId", tenantId);
        }

        IPage<BusiDemandEntity> page = getPage(params, Constant.CREATE_DATE, false);
        List<BusiDemandDTO> list = baseDao.getList(page, params);
        PageData<BusiDemandDTO> pageData = getPageData(list, page.getTotal(), BusiDemandDTO.class);

        complement(pageData);

        return pageData;
    }

    @Override
    public BusiDemandDetailDTO getDeamndDetailByTenantId(Long id) {
        //查询需求
        Long tenantId = SecurityUser.getTenantId();
        BusiDemandEntity busiDemandEntity = busiDemandDao.selectById(id);
        if (busiDemandEntity == null) {
            log.error("未查到需求!");
            throw new CustomException("未查到需求!");
        }

        BusiDemandDetailDTO busiDemandDetailDTO = ConvertUtils.sourceToTarget(busiDemandEntity, BusiDemandDetailDTO.class);

        busiDemandDetailDTO.setDemandId(busiDemandEntity.getId());
        //查询商品信息获取商品类别  快照表
        BusiDemandProductSnapshotDTO productSnapshotDTO = busiDemandProductSnapshotService.get(busiDemandEntity.getProductId());
        if (Objects.nonNull(productSnapshotDTO)) {
            busiDemandDetailDTO.setProductCategory(productSnapshotDTO.getFirstParentName() + ">>" + productSnapshotDTO.getSecondParentName() + ">>" + productSnapshotDTO.getName());
        }
        //获取计量单位字典值
        if (productSnapshotDTO != null && StringUtils.isNotBlank(productSnapshotDTO.getSpec())) {
            busiDemandDetailDTO.setProductUnit(sysDictDataService.getJoiningValue(DataTypeEnum.PRODUCT_UNIT, String.valueOf(busiDemandEntity.getProductUnit())));
        }
        //需求状态
        if (busiDemandEntity.getDemandStatus() != null) {
            busiDemandDetailDTO.setDemandStatusName(sysDictDataService.getValue(DataTypeEnum.DEMAND_STATUS, String.valueOf(busiDemandEntity.getDemandStatus())));
        }
        //支付状态
        if (busiDemandEntity.getPayStatus() != null) {
            busiDemandDetailDTO.setPayStatusName(sysDictDataService.getValue(DataTypeEnum.PAY_STATUS, String.valueOf(busiDemandEntity.getPayStatus())));
        }
        //补全收货地址 快照获取
        BusiDemandAddressSnapshotDTO addressSnapshotDTO = busiDemandAddressSnapshotService.get(busiDemandDetailDTO.getAddressId());
        Optional.ofNullable(addressSnapshotDTO).ifPresent(o -> complementAddress(busiDemandDetailDTO, addressSnapshotDTO));
        // 补全发票抬头信息 快照获取
        BusiDemandInvoiceHeadSnapshotDTO invoiceHeadSnapshotEntity = busiDemandInvoiceHeadSnapshotService.get(busiDemandDetailDTO.getInvoiceHeadId());
        Optional.ofNullable(invoiceHeadSnapshotEntity).ifPresent(o -> complementInvoiceHead(busiDemandDetailDTO, invoiceHeadSnapshotEntity));

        return busiDemandDetailDTO;
    }

    private void complementAddress(BusiDemandDetailDTO busiDemandDetailVO, BusiDemandAddressSnapshotDTO addressSnapshotDTO) {
        Optional.ofNullable(busiDemandDetailVO).ifPresent(vo -> {
            vo.setAddressId(addressSnapshotDTO.getId());
            vo.setTag(addressSnapshotDTO.getTag());
            vo.setAddress(addressSnapshotDTO.getAddress());
            vo.setConsignee(addressSnapshotDTO.getConsignee());
            vo.setAddressMobile(addressSnapshotDTO.getAddressMobile());
            vo.setProvinceId(addressSnapshotDTO.getProvinceId());
            vo.setProvinceName(addressSnapshotDTO.getProvinceName());
            vo.setCityId(addressSnapshotDTO.getCityId());
            vo.setCityName(addressSnapshotDTO.getCityName());
            vo.setAreaId(addressSnapshotDTO.getAreaId());
            vo.setAreaName(addressSnapshotDTO.getAreaName());
        });
    }

    private void complementInvoiceHead(BusiDemandDetailDTO busiDemandDetailVO, BusiDemandInvoiceHeadSnapshotDTO invoiceHeadSnapshotDTO) {
        Optional.ofNullable(busiDemandDetailVO).ifPresent(vo -> {
            vo.setInvoiceHeadId(invoiceHeadSnapshotDTO.getId());
            vo.setInvoiceTypeName(sysDictDataService.getValue(DataTypeEnum.INVOICE_TYPE, String.valueOf(invoiceHeadSnapshotDTO.getInvoiceType())));
            vo.setInvoiceType(invoiceHeadSnapshotDTO.getInvoiceType());
            vo.setInvoiceCode(invoiceHeadSnapshotDTO.getInvoiceCode());
            vo.setInvoiceHead(invoiceHeadSnapshotDTO.getInvoiceHead());
            vo.setInvoiceBankAccount(invoiceHeadSnapshotDTO.getInvoiceBankAccount());
            vo.setInvoiceMobile(invoiceHeadSnapshotDTO.getInvoiceMobile());
            vo.setInvoiceBankName(invoiceHeadSnapshotDTO.getInvoiceBankName());
            vo.setInvoiceAddress(invoiceHeadSnapshotDTO.getInvoiceAddress());
            vo.setInvoiceEmail(invoiceHeadSnapshotDTO.getInvoiceEmail());
        });

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveDemand(BusiDemandDTO dto) {
        //系统管理员，不能新建需求
        if (UserUtils.isSuperAdmin()) {
            log.error("超级管理员不允许新建需求！");
            throw new CustomException("超级管理员不允许新建需求！");
        }
        Long tenantId = SecurityUser.getTenantId();
        if (dto.getDemandTotal().compareTo(new BigDecimal(0)) < 0){
            throw new CustomException("需求数量必须为正整数");
        }
        //计算税金额  ----这里先设置为null,后续需要做处理
        //卖家收款金额 单价乘以数量
        BigDecimal sellerReceivePrice = dto.getPrice().multiply(dto.getDemandTotal()).setScale(6, RoundingMode.UP);
        //税率
        BigDecimal taxRate = new BigDecimal("0.001");
        //服务费率
        BigDecimal serviceRate = new BigDecimal("0.001");
        // 1
        BigDecimal unit1 = new BigDecimal(1);
        //不含增值税金额
        dto.setNoVatPrice(sellerReceivePrice.multiply((serviceRate.add(unit1))).setScale(2,RoundingMode.UP));
        //增值税
        dto.setVat(sellerReceivePrice.multiply(taxRate.divide(
                unit1.subtract(taxRate), 6,RoundingMode.UP)).setScale(2,RoundingMode.UP));
        //合同总价
        dto.setContractTotalPrice(sellerReceivePrice
                .multiply((unit1.divide(unit1.subtract(taxRate),6, RoundingMode.UP))
                        .add(serviceRate).setScale(6,RoundingMode.UP)).setScale(2,RoundingMode.UP));
        //卖家收款金额
        dto.setSellerReceivePrice(sellerReceivePrice);
        //平台代收税费
        dto.setPlatformTakeTaxPrice(sellerReceivePrice.multiply(
                (taxRate.divide(unit1.subtract(taxRate),6, RoundingMode.UP))
                        .add(serviceRate).setScale(6,RoundingMode.UP)).setScale(2,RoundingMode.UP));

        dto.setDemandNo(String.valueOf(SnowFlakeUtils.getInstance().nextId()));
        dto.setDataSource(0);//需求来源
        dto.setDemandStatus(2);//需求状态 履约中
        dto.setPayStatus(1);//支付状态0  已支付

        //新增一条支付记录
        financeInsert(dto, sellerReceivePrice);
        dto.setDemandId(tenantId);
        dto.setTenantId(tenantId);
        Optional.ofNullable(SecurityUser.getTenantId()).ifPresent(o -> {
            SysTenantEntity sysTenantEntity = sysTenantDao.selectById(SecurityUser.getTenantId());
            Optional.ofNullable(SecurityUser.getTenantId()).ifPresent(o1 -> {
                dto.setTenantName(sysTenantEntity.getName());
                dto.setDemandName(sysTenantEntity.getName());
                dto.setTenantType(sysTenantEntity.getTenantType());
            });
        });
        //新建需求默认自发
        dto.setDemandSourceType(0);
        if (dto.getAssignIds() != null && dto.getAssignIds().length > 0) {
            dto.setAssignType(0);
        } else {
            dto.setAssignType(1);
        }
        //增加需求相关的快照表
        demandSnapshotSave(dto);
        this.save(dto);

        // 添加关联表数据
        demandAssignInsert(dto.getAssignIds(), tenantId, tenantId, dto.getInvoiceTypeId());

    }

    /**
     * 添加需求客户关联表
     *
     * @param assignIds     指派方客户ID
     * @param demandId      需求方客户ID
     * @param tenantId      甲方客户ID
     * @param invoiceTypeId 发票类型ID
     */
    private void demandAssignInsert(String[] assignIds, Long demandId, Long tenantId, Long invoiceTypeId) {
        List<BusiDemandTenantEntity> demandTenantEntities = new ArrayList<>();
        if (assignIds != null && assignIds.length > 0) {
            for (String assignId : assignIds) {
                BusiDemandTenantEntity busiDemandTenantEntity = new BusiDemandTenantEntity();
                busiDemandTenantEntity.setAssignId(Long.valueOf(assignId));
                busiDemandTenantEntity.setTenantId(tenantId);
                busiDemandTenantEntity.setDemandId(demandId);
                busiDemandTenantEntity.setInvoiceTypeId(invoiceTypeId);
                demandTenantEntities.add(busiDemandTenantEntity);
            }
        }
        busiDemandTenantService.insertBatch(demandTenantEntities);
    }

    /**
     * 添加支付记录
     *
     * @param dto
     * @param sellerReceivePrice
     */
    private void financeInsert(BusiDemandDTO dto, BigDecimal sellerReceivePrice) {
        BusiFinanceDTO busiFinanceDTO = new BusiFinanceDTO();
        busiFinanceDTO.setDemandId(dto.getDemandId());
        busiFinanceDTO.setDemandNo(dto.getDemandNo());
        busiFinanceDTO.setOrderAmount(sellerReceivePrice);
        busiFinanceDTO.setOrderStatus(1);
        busiFinanceDTO.setPayWay(0);
        busiFinanceDTO.setOrderSourceType(0);
        busiFinanceDTO.setSupplyId(null);
        busiFinanceDTO.setCreateDate(new Date());
        busiFinanceDTO.setUpdateDate(new Date());
        busiFinanceService.save(busiFinanceDTO);
    }

    private void demandSnapshotSave(BusiDemandDTO dto) {
        BusiDemandAddressSnapshotEntity addressSnapshotEntity = busiDemandAddressSnapshotService.saveDemandSnapshot(dto.getId(), dto.getAddressId());
        dto.setAddressId(addressSnapshotEntity.getId());
        BusiDemandProductSnapshotEntity productSnapshotEntity = busiDemandProductSnapshotService.saveDemandSnapshot(dto.getId(), dto.getProductId());
        dto.setProductId(productSnapshotEntity.getId());
        BusiDemandInvoiceHeadSnapshotEntity invoiceHeadSnapshotEntity = busiDemandInvoiceHeadSnapshotService.saveDemandSnapshot(dto.getId(), dto.getInvoiceHeadId());
        dto.setInvoiceHeadId(invoiceHeadSnapshotEntity.getId());
        /*BusiDemandTenantSnapshotEntity demandTenantSnapshotEntity = busiDemandTenantSnapshotService.saveDemandSnapshot(dto.getId(), dto.getTenantId());
        dto.setTenantId(demandTenantSnapshotEntity.getId());*/
       /* BusiDemandDemandSnapshotEntity demandDemandSnapshotEntity = busiDemandDemandSnapshotService.saveDemandSnapshot(dto.getId(), dto.getDemandId());
        dto.setDemandId(demandDemandSnapshotEntity.getId());*/
        //供应方待定
        //busiDemandPerformanceSnapshotService.saveDemandSnapshot(dto.getDemandId(), dto.getPerformanceId());
    }

    @Override
    public List<SysTenantDTO> getTenantByTenantName(String name) {

        Long tenantId = SecurityUser.getTenantId();
        LambdaQueryWrapper<SysTenantBindingsEntity> lambdaQueryWrapper = new LambdaQueryWrapper<SysTenantBindingsEntity>().eq(tenantId != null, SysTenantBindingsEntity::getTenantId, tenantId);
        List<SysTenantBindingsEntity> sysTenantBindingsEntities = sysTenantBindingsDao.selectList(lambdaQueryWrapper);
        if (CollectionUtils.isEmpty(sysTenantBindingsEntities)) {
            return new ArrayList<>();
        }
        List<Long> bindings = sysTenantBindingsEntities.stream().map(SysTenantBindingsEntity::getBindingTenantId).filter(Objects::nonNull).collect(toList());
        LambdaQueryWrapper<SysTenantEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(SysTenantEntity::getId, bindings).like(name != null, SysTenantEntity::getName, name);
        List<SysTenantEntity> sysTenantEntityList = sysTenantDao.selectList(queryWrapper);

        //转换
        List<SysTenantDTO> sysTenantDTOS = ConvertUtils.sourceToTarget(sysTenantEntityList, SysTenantDTO.class);

        return sysTenantDTOS;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void transferDemandOrder(TransferOrderDTO transferOrderDto) {
        // 修改原需求状态
        BusiDemandDTO busiDemandDTO = this.get(transferOrderDto.getId());

        // 获取所有相关客户信息
        Long tenantId = SecurityUser.getTenantId();
        ArrayList<String> tenantIdList = Lists.newArrayList(Optional.ofNullable(transferOrderDto.getAssignIds()).orElse(new String[]{}));
        tenantIdList.add(String.valueOf(tenantId));
        tenantIdList.add(String.valueOf(busiDemandDTO.getTenantId()));
        List<SysTenantEntity> sysTenantEntities = sysTenantDao.selectBatchIds(tenantIdList);
        Map<Long, SysTenantEntity> map = new HashMap<>();
        if (CollectionUtils.isNotEmpty(sysTenantEntities)) {
            map = sysTenantEntities.stream().collect(Collectors.toMap(SysTenantEntity::getId, Function.identity()));
        }

        //校验
        SysTenantEntity demandTenantEntity = map.get(busiDemandDTO.getTenantId());
        Optional.ofNullable(demandTenantEntity).orElseThrow(() -> new CustomException("需求数据异常，缺少tenantId数据！"));
        if (Objects.equals(SecurityUser.getTenantType(), 2)) {
            throw new CustomException("散户不允许转单！");
        }
        if (Objects.equals(demandTenantEntity.getTenantType(), SecurityUser.getTenantType())) {
            throw new CustomException("不允许接同类型用户的订单！");
        }
        if (Objects.equals(demandTenantEntity.getTenantType(), 1)) {
            throw new CustomException("公司类型的订单不允许转单！");
        }
        //计算新需求需求数量
        BigDecimal newBusiDemandTotal = new BigDecimal(0);
        if (busiDemandDTO.getDemandTotal() != null && busiDemandDTO.getAlreadySupplyNum() != null) {
            newBusiDemandTotal = new BigDecimal(transferOrderDto.getTransferNumber());
        }
        if (newBusiDemandTotal.compareTo(BigDecimal.ZERO) <= 0) {
            throw new CustomException("总需求数量为0或小于0！");
        }
        //更新订单状态
        busiDemandDTO.setAlreadySupplyNum(busiDemandDTO.getAlreadySupplyNum().add(new BigDecimal(transferOrderDto.getTransferNumber())));
        //增加供应方快照表
        busiDemandDTO.setPerformanceId(String.valueOf(SecurityUser.getTenantId()));
        /*BusiDemandPerformanceSnapshotEntity performanceSnapshotEntity = busiDemandPerformanceSnapshotService.saveDemandSnapshot(busiDemandDTO.getDemandId(), SecurityUser.getTenantId());
        busiDemandDTO.setPerformanceId(String.valueOf(performanceSnapshotEntity.getId()));*/
        BigDecimal total = new BigDecimal(String.valueOf(busiDemandDTO.getDemandTotal()));
        BigDecimal aleadySupplyNum = new BigDecimal(String.valueOf(busiDemandDTO.getAlreadySupplyNum()));
        //BigDecimal transferNum = new BigDecimal(transferOrderDto.getTransferNumber());

        if (total.compareTo(aleadySupplyNum) == 0) {
            //已完成
            busiDemandDTO.setDemandStatus(3);
        } else {
            busiDemandDTO.setDemandStatus(2);//设置为履约中
        }
        this.update(busiDemandDTO);

        //新建需求、支付记录
        SysTenantEntity tenantEntity = map.get(tenantId);
        BusiDemandDTO demandDTO = newBusiDemandInsert(busiDemandDTO, tenantEntity, newBusiDemandTotal);
        financeInsert(demandDTO, NumberUtil.mul(demandDTO.getPrice(), demandDTO.getDemandTotal()).setScale(6, RoundingMode.UP));

        //处理关联关系
        if (2 == transferOrderDto.getType()) {
            demandAssignInsert(transferOrderDto.getAssignIds(), busiDemandDTO.getDemandId(), tenantId, busiDemandDTO.getInvoiceTypeId());
        }
    }

    /**
     * 创建新需求
     *
     * @param busiDemandDTO
     * @param tenantEntity
     * @param newBusiDemandTotal
     */
    private BusiDemandDTO newBusiDemandInsert(BusiDemandDTO busiDemandDTO, SysTenantEntity tenantEntity, BigDecimal newBusiDemandTotal) {

        //新建需求
        BusiDemandDTO newBusiDemandDTO = new BusiDemandDTO();
        BeanUtils.copyProperties(busiDemandDTO, newBusiDemandDTO);
        //设置转单需求初始化数据
        newBusiDemandDTO.setDemandTotal(newBusiDemandTotal);
        newBusiDemandDTO.setTenantId(SecurityUser.getTenantId());
        newBusiDemandDTO.setAlreadySupplyNum(BigDecimal.ZERO);
        newBusiDemandDTO.setDemandSourceType(1); //转发
        newBusiDemandDTO.setDemandStatus(2);
        newBusiDemandDTO.setDemandNo(SnowFlakeUtils.getNextId());
        newBusiDemandDTO.setCreator(SecurityUser.getUserId());
        newBusiDemandDTO.setCreateDate(new Date());
        newBusiDemandDTO.setUpdateDate(new Date());
        newBusiDemandDTO.setPerformanceId(null);
        newBusiDemandDTO.setId(null);
        newBusiDemandDTO.setTenantName(tenantEntity.getName());
        newBusiDemandDTO.setTenantType(tenantEntity.getTenantType());
        this.save(newBusiDemandDTO);
        return newBusiDemandDTO;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void closeDemand(Long id, String reason) {

        BusiDemandEntity busiDemandEntity = this.selectById(id);
        if (Objects.equals(busiDemandEntity.getDemandStatus(), 3)) {
            throw new CustomException("不能关闭已完成的需求！");
        }
        //需求客户关系表更新
        LambdaUpdateWrapper<BusiDemandTenantEntity> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(id != null, BusiDemandTenantEntity::getDemandId, id).set(BusiDemandTenantEntity::getDeleted, 1);
        busiDemandTenantDao.update(null, updateWrapper);
        //更新需求表的状态
        LambdaUpdateWrapper<BusiDemandEntity> demandEntityLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        demandEntityLambdaUpdateWrapper.eq(id != null, BusiDemandEntity::getId, id).set(BusiDemandEntity::getCloseReason, reason).set(BusiDemandEntity::getDemandStatus, 4);
        busiDemandDao.update(null, demandEntityLambdaUpdateWrapper);
    }

    @Override
    public Result<BusiDemandDetailDTO> getInvoiceAndAddress(Long demandId) {
        //系统管理员，不能新建需求
        if (UserUtils.isSuperAdmin()) {
            log.error("超级管理员不允许新建需求！");
            throw new CustomException("超级管理员不允许新建需求！");
        }
        Long tenantId = SecurityUser.getTenantId();
        if (demandId != null) {
            tenantId = demandId;
        }
        //获取发票字典值
        BusiDemandDetailDTO busiDemandDetailDTO = new BusiDemandDetailDTO();

        // 补全地址
        LambdaQueryWrapper<BusiAddressEntity> queryWrapper = new LambdaQueryWrapper<BusiAddressEntity>().eq(BusiAddressEntity::getTenantId, tenantId).eq(BusiAddressEntity::getDeleted, 0).eq(BusiAddressEntity::getDefaulted, 0);
        BusiAddressEntity busiAddressEntity = busiAddressDao.selectOne(queryWrapper);
        if (busiAddressEntity == null) {
            log.error("未查到该租户下收货信息");
            throw new CustomException("未查到该租户下收货信息");
        }
        BusiDemandAddressSnapshotDTO addressSnapshotDTO = ConvertUtils.sourceToTarget(busiAddressEntity, BusiDemandAddressSnapshotDTO.class);
        complementAddress(busiDemandDetailDTO, addressSnapshotDTO);
        // 补全发票抬头
        //查询发票信息
        LambdaQueryWrapper<BusiInvoiceHeadEntity> queryWrapperBusiInvoiceHead = new LambdaQueryWrapper<BusiInvoiceHeadEntity>()
                .eq(BusiInvoiceHeadEntity::getTenantId, tenantId).eq(BusiInvoiceHeadEntity::getDeleted, 0).eq(BusiInvoiceHeadEntity::getDefaulted, 0);
        BusiInvoiceHeadEntity busiInvoiceHeadEntity = busiInvoiceHeadDao.selectOne(queryWrapperBusiInvoiceHead);
        if (busiInvoiceHeadEntity == null) {
            log.error("未查到该租户下发票信息");
            throw new CustomException("未查到该租户下发票信息");
        }
        BusiDemandInvoiceHeadSnapshotDTO invoiceHeadSnapshotDTO = ConvertUtils.sourceToTarget(busiInvoiceHeadEntity, BusiDemandInvoiceHeadSnapshotDTO.class);
        complementInvoiceHead(busiDemandDetailDTO, invoiceHeadSnapshotDTO);

        return new Result<BusiDemandDetailDTO>().ok(busiDemandDetailDTO);
    }

}
